package com.ruoyi.system.utils;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.domain.SysContracts;
import com.ruoyi.system.domain.SysUserScok;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.SysContractsService;
import com.ruoyi.system.service.SysUserScokService;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import io.swagger.models.auth.In;
import io.vertx.core.Vertx;
import io.vertx.mqtt.MqttServer;
import org.apache.logging.log4j.spi.DefaultThreadContextStack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import static com.ruoyi.system.domain.Commonlist.buyList;
import static com.ruoyi.system.domain.Commonlist.sellList;


@Service
public class MarketService {
    @Autowired
    private ISysUserService userService;
    @Autowired
    private SysContractsService contractsService;
    @Autowired
    private SysUserScokService userScokService;

    private ConcurrentLinkedQueue<String> messageQueue = new ConcurrentLinkedQueue<>();
    private static final    List<SysContracts> buylist = new ArrayList<>();; // 重用实例
    private static final    List<SysContracts> selllist = new ArrayList<>();; // 重用实例

    public MarketService() {
        System.out.println("start mqtt server.....");
        Vertx vertx = Vertx.vertx();
        MqttServer  mqttServer = MqttServer.create(vertx);
        mqttServer.endpointHandler(endpoint -> {
            // accept connection from the remote client
            endpoint.accept(false);
            endpoint.publishHandler(message -> {
                String topic = message.topicName();  // 获取主题
                try {
                    String payload = new String(message.payload().getBytes());
                    JSONArray jsonArray = new JSONArray(payload);
                    // 根据不同的主题进行不同的处理
                    if (topic.equals("buy")) {
                        for (int i = 0; i < jsonArray.size(); i++) {
                            JSONObject jsonObject = jsonArray.getJSONObject(i);
                            SysContracts three = new SysContracts();
                            three.setId(jsonObject.getInt("id"));
                            three.setUname(String.valueOf(jsonObject.getInt("uname")));
                            three.setStatus(jsonObject.getInt("status"));
                            three.setScokName(String.valueOf(jsonObject.getInt("scokName")));
                            three.setIndate(jsonObject.getDate("indate"));
                            three.setScokPrice(jsonObject.getBigDecimal("scokPrice"));
                            three.setFalg(Integer.valueOf(jsonObject.getStr("falg")));
                            three.setStockId(jsonObject.getStr("stockId"));
                            three.setNum(jsonObject.getInt("num"));
                            three.setUserId(jsonObject.getInt("userId"));
                            buylist.add(three);
                        }
                        System.out.println("Mqtt收到的请求买家排序后的是: ......................." + buyList+"数量++++++++++"+buyList.size());
                        // 处理主题 1 的逻辑
                    } else if (topic.equals("sell")) {
                        // 处理主题 2 的逻辑
                        for (int i = 0; i < jsonArray.size(); i++) {
                            JSONObject jsonObject = jsonArray.getJSONObject(i);
                            SysContracts three = new SysContracts();
                            three.setId(jsonObject.getInt("id"));
                            three.setUname(String.valueOf(jsonObject.getInt("uname")));
                            three.setStatus(jsonObject.getInt("status"));
                            three.setScokName(String.valueOf(jsonObject.getInt("scokName")));
                            three.setIndate(jsonObject.getDate("indate"));
                            three.setScokPrice(jsonObject.getBigDecimal("scokPrice"));
                            three.setFalg(Integer.valueOf(jsonObject.getStr("falg")));
                            three.setStockId(jsonObject.getStr("stockId"));
                            three.setNum(jsonObject.getInt("num"));
                            three.setUserId(jsonObject.getInt("userId"));
                            selllist.add(three);
                        }
                        System.out.println("Mqtt收到的请求卖家排序后的是: ......................." + sellList+"数量++++++++++"+sellList.size());
                    }


                } catch (Exception e) {
                    System.out.println("receive msg, bug got error.");
                    e.printStackTrace();
                }
            });
//            sellList.clear();
//            buyList.clear();
            //撮合
            if(!buylist.isEmpty()&&!selllist.isEmpty()){
                meatc();
            }

        }).listen(1883, "127.0.0.1").onFailure(throwable -> System.out.println("error on start mqtt"));

    }

//    private void matchingContracts() {
//        List<SysContracts> contractsWithSameStockAndPrice = msgList.stream()
//                .map(payload -> JSONUtil.toBean(payload, SysContracts.class))
//                .filter(c -> {
//                    boolean foundPair = false;
//                    for (String otherContractPayload : messageQueue) {
//                        SysContracts other = JSONUtil.toBean(otherContractPayload, SysContracts.class);
//                        if (c.getStockId().equals(other.getStockId()) && c.getScokPrice().equals(other.getScokPrice())
//                                && ((c.getFalg() == 0 && other.getFalg() == 1) || (c.getFalg() == 1 && other.getFalg() == 0))) {
//                            foundPair = true;
//                            break;
//                        }
//                    }
//                    return foundPair;
//                })
//                .collect(Collectors.toList());
//        System.out.println("cuohe chengg de you "+contractsWithSameStockAndPrice+"bjvbjvf"+contractsWithSameStockAndPrice.size());
//        // 打印匹配结果
//        contractsWithSameStockAndPrice.forEach(
//                contract ->{
//                    if (contract.getFalg() == 0) {
//                        System.out.println("匹配的合同: " + contract);
//                        // 减钱逻辑
//                        System.out.println("买入的请求进行减钱，加持仓");
//                        addMonenyandCang(contract);
//                        // 这里实现具体的减钱操作
//                    } else {
//                        // 加钱逻辑
//                        // 这里实现具体的加钱操作
//                        System.out.println("匹配的合同: " + contract);
//                        System.out.println("maichu的请求进行加钱，减去持仓");
//                        jianMonenyandCang(contract);
//                    }
//
//                }
//        );
//
//    }
    private void meatc() {
        Iterator<SysContracts> buyIterator = buylist.iterator();
        while (buyIterator.hasNext()) {
            SysContracts buyContract = buyIterator.next();
            Iterator<SysContracts> sellIterator = selllist.iterator();
            boolean matched = false;
            while (sellIterator.hasNext()) {
                SysContracts sellContract = sellIterator.next();
                if (buyContract.getScokPrice().compareTo(sellContract.getScokPrice()) >= 0 &&
                        buyContract.getStockId().equals(sellContract.getStockId())) {
                    // 撮合成功
                    System.out.println("撮合成功的数据: " + buyContract + " 卖家: " + sellContract);
                    jianMonenyandCang(sellContract);
                    addMonenyandCang(buyContract);
                    // 计算需要减少的数量，取较小的那个
                    int minQuantity = Math.min(buyContract.getNum(), sellContract.getNum());

                    // 修改数量
                    buyContract.setNum(buyContract.getNum() - minQuantity);
                    sellContract.setNum(sellContract.getNum() - minQuantity);
                    // 如果数量为0，则从列表中移除
                    if (buyContract.getNum() == 0) {
                        buyIterator.remove(); // 使用迭代器来安全地移除元素
                        matched = true; // 标记已经撮合
                    }
                    if (sellContract.getNum() == 0) {
                        sellIterator.remove(); // 使用迭代器来安全地移除元素
                    }
                    break; // 跳出内部循环
                }
            }
        }
    }
    @Transactional
     void jianMonenyandCang(SysContracts contract) {
        SysUser sysUser = userService.selectUserById(contract.getUserId().longValue());
        BigDecimal money = sysUser.getMoney();
        System.out.println("该账户下的前"+sysUser.getUserName()+"----"+sysUser.getMoney());
        BigDecimal add = money.add(contract.getScokPrice());
        System.out.println("maijiadefzi1111+++++++++"+add);
        userService.updateMoney(add,contract.getUserId());
        System.out.println("-----修改用户资金成功");
        //加入持仓
        addStock(contract);
        //修改委托状态
        updateContrat(contract);
    }
    @Transactional
    void addMonenyandCang(SysContracts contract) {
         //chauxunyonghujine
        SysUser sysUser = userService.selectUserById(contract.getUserId().longValue());
        BigDecimal money = sysUser.getMoney();
        System.out.println("该账户下的前"+sysUser.getUserName()+"----"+sysUser.getMoney());
        BigDecimal add = money.subtract(contract.getScokPrice());
        System.out.println("maijiadefzi2222222222+++++++++"+add);
        userService.updateMoney(add,contract.getUserId());
        System.out.println("-----修改用户资金成功");
        //加入持仓
        addStock(contract);
        //修改委托状态
        updateContrat(contract);
    }

    private void updateContrat(SysContracts contract) {

        contractsService.updateStatus(contract.getUserId(),contract.getStockId(),contract.getFalg(),contract.getNum());
        System.out.println("修改委托完毕"+contract);
    }

    /**
     *  加入持仓
     */
    public void addStock(SysContracts contract){
        SysUserScok sysUserScok1 = new SysUserScok();
        sysUserScok1.setScokId(contract.getStockId());
        sysUserScok1.setNum(contract.getNum());
        sysUserScok1.setUname(contract.getUname());
        sysUserScok1.setScokPrice(contract.getScokPrice());
        sysUserScok1.setIndate(contract.getIndate());
        sysUserScok1.setScokName(contract.getScokName());
        sysUserScok1.setUserId(contract.getUserId());

        SysUserScok sysUserScok = userScokService.selectById(contract.getUserId().longValue(), contract.getStockId());
        if(sysUserScok!=null){
            userScokService.updateByScok(sysUserScok1);
        }else {
            userScokService.insertMySock(sysUserScok1);
        }
    }
}
